import type { RouteLocationNormalizedLoaded } from 'vue-router'
import { defineStore } from 'pinia'
import { findIndex } from '@/utils'
import { router } from '@/router'
import { computed, ComputedRef, ref } from 'vue'

export interface TagsViewState {
  visitedViews: RouteLocationNormalizedLoaded[]
  cachedViews: Set<string>
  selectedTag?: RouteLocationNormalizedLoaded
}

export default defineStore<string, Record<string, any>>('tagsViewStore', (): Record<string, any> => {
  const visitedViews = ref<RouteLocationNormalizedLoaded[]>([])
  const cachedViews = ref<Set<string>>(new Set())
  const selectedTag = ref<RouteLocationNormalizedLoaded>()

  const getVisitedViews = computed(() => visitedViews.value)
  const getCachedViews: ComputedRef<string[]> = computed(() => Array.from(cachedViews.value))
  const getSelectedTag: ComputedRef<RouteLocationNormalizedLoaded> = computed(() => selectedTag.value)

  // 新增缓存和tag
  function addView(view: RouteLocationNormalizedLoaded): void {
    addVisitedView(view)
    addCachedView()
  }

  // 新增tag
  function addVisitedView(view: RouteLocationNormalizedLoaded) {
    if (visitedViews.value.some((v) => v.path === view.path)) return
    if (view.meta?.noTagsView) return
    visitedViews.value.push(
      Object.assign({}, view, {
        title: view.meta?.label || 'no-name'
      })
    )
  }

  // 新增缓存
  function addCachedView() {
    const cacheMap: Set<string> = new Set()
    for (const v of visitedViews.value) {
      // const item = getRawRoute(v)
      const item = v
      const needCache = !item?.meta?.noCache
      if (!needCache) {
        continue
      }
      const name = item.name as string
      cacheMap.add(name)
    }
    if (Array.from(cachedViews.value).sort().toString() === Array.from(cacheMap).sort().toString())
      return
    cachedViews.value = cacheMap
  }

  // 删除某个
  function delView(view: RouteLocationNormalizedLoaded) {
    delVisitedView(view)
    addCachedView()
  }

  // 删除tag
  function delVisitedView(view: RouteLocationNormalizedLoaded) {
    for (const [i, v] of visitedViews.value.entries()) {
      if (v.path === view.path) {
        visitedViews.value.splice(i, 1)
        break
      }
    }
  }

  // 删除缓存
  function delCachedView() {
    const route = router.currentRoute.value
    const index = findIndex(getCachedViews.value, (v) => v === route.name)
    if (index > -1) {
      cachedViews.value.delete(getCachedViews.value[index])
    }
  }

  // 删除所有缓存和tag
  function delAllViews() {
    delAllVisitedViews()
    addCachedView()
  }

  // 删除所有tag
  function delAllVisitedViews() {
    // const userStore = useUserStoreWithOut()

    // const affixTags = visitedViews.filter((tag) => tag.meta.affix)
    // visitedViews = userStore.getUserInfo
    //   ? visitedViews.filter((tag) => tag?.meta?.affix)
    //   : []
    visitedViews.value = visitedViews.value.filter((tag) => tag?.meta?.affix)
  }

  // 删除其它
  function delOthersViews(view: RouteLocationNormalizedLoaded) {
    delOthersVisitedViews(view)
    addCachedView()
  }

  // 删除其它tag
  function delOthersVisitedViews(view: RouteLocationNormalizedLoaded) {
    visitedViews.value = visitedViews.value.filter((v) => {
      return v?.meta?.affix || v.path === view.path
    })
  }

  // 删除左侧
  function delLeftViews(view: RouteLocationNormalizedLoaded) {
    const index = findIndex(visitedViews.value, (v) => v.path === view.path)
    if (index > -1) {
      visitedViews.value = visitedViews.value.filter((v, i) => {
        return v?.meta?.affix || v.path === view.path || i > index
      })
      addCachedView()
    }
  }

  // 删除右侧
  function delRightViews(view: RouteLocationNormalizedLoaded) {
    const index = findIndex(visitedViews.value, (v) => v.path === view.path)
    if (index > -1) {
      visitedViews.value = visitedViews.value.filter((v, i) => {
        return v?.meta?.affix || v.path === view.path || i < index
      })
      addCachedView()
    }
  }

  function updateVisitedView(view: RouteLocationNormalizedLoaded) {
    for (let v of visitedViews.value) {
      if (v.path === view.path) {
        v = Object.assign(v, view)
        break
      }
    }
  }

  // 设置当前选中的tag
  function setSelectedTag(tag: RouteLocationNormalizedLoaded) {
    selectedTag.value = tag
  }

  function setTitle(title: string, path?: string) {
    for (const v of visitedViews.value) {
      if (v.path === (path ?? selectedTag.value?.path)) {
        v.meta.label = title
        break
      }
    }
  }

  return {
    getVisitedViews,
    getCachedViews,
    getSelectedTag,
    addView,
    addCachedView,
    addVisitedView,
    delAllViews,
    delAllVisitedViews,
    delCachedView,
    delLeftViews,
    delOthersViews,
    delOthersVisitedViews,
    delRightViews,
    delView,
    delVisitedView,
    updateVisitedView,
    setSelectedTag,
    setTitle
  }
})
